package com.common.config.orm;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.session.LocalCacheScope;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

@Configuration
@MapperScan(basePackages = {"com.core.**.dao", "com.core.**.mapper"}, sqlSessionTemplateRef = MysqlDataSourceConfig.MysqlSqlSessionTemplate)
public class MysqlDataSourceConfig {

    public static final String MysqlDataSource = "mysqlDataSource";
    public static final String MysqlTransactionManager = "mysqlTransactionManager";
    public static final String MysqlSqlSessionFactory = "mysqlSqlSessionFactory";
    public static final String MysqlSqlSessionTemplate = "mysqlSqlSessionTemplate";
    public static final String MysqlMapperLocations = "classpath*:mapper/mysql/**/*.xml";

    // 1. 只配置 Druid 数据源（MyBatis-Plus 会自动使用这个数据源）
    @Bean(name = MysqlDataSource)
    @ConfigurationProperties(prefix = "spring.datasource.mysql")
    @Primary
    public DataSource mysqlDataSource() {
        return new DruidDataSource();
    }

    // 2. 自定义 SqlSessionFactory（使用 MyBatis-Plus 增强版 Bean，注入数据源和拦截器）
    @Bean(name = MysqlSqlSessionFactory)
    @Primary
    public SqlSessionFactory mysqlSqlSessionFactory(@Qualifier(MysqlDataSource) DataSource dataSource,
                                                    @Qualifier("mysqlPlusInterceptor") MybatisPlusInterceptor mysqlPlusInterceptor,
                                                    @Qualifier("globalConfig") GlobalConfig globalConfig) throws Exception {
        //mybatis应该使用  SqlSessionFactoryBean
        //SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();

        //mybatis-plus应该使用  MybatisSqlSessionFactoryBean  否则无法使用baseMapper
        // 关键：使用 MyBatis-Plus 的 MybatisSqlSessionFactoryBean，而非 MyBatis 原生的
        MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        mybatisSqlSessionFactoryBean.setDataSource(dataSource);

        // 扫描 Mapper.xml 文件
        mybatisSqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources(MysqlMapperLocations));

        // 注入 MyBatis-Plus 拦截器（分页等功能生效的核心）
        mybatisSqlSessionFactoryBean.setPlugins(mysqlPlusInterceptor);

        // 设置全局配置
        mybatisSqlSessionFactoryBean.setGlobalConfig(globalConfig);

        // 自定义 MyBatis 基础配置（保留不变）
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setLogImpl(org.apache.ibatis.logging.stdout.StdOutImpl.class); // 控制台日志打印
        configuration.setMapUnderscoreToCamelCase(true); // 驼峰映射命名
        configuration.setCacheEnabled(false); // 禁用二级缓存
        // 一级缓存作用域，默认为 SESSION，现在设为 STATEMENT
        // 因为一级缓存可能间接的会导致，数据实时性差，影响数据的一致性
        configuration.setLocalCacheScope(LocalCacheScope.STATEMENT);
        mybatisSqlSessionFactoryBean.setConfiguration(configuration);

        return mybatisSqlSessionFactoryBean.getObject();
    }

    // 3. 事务管理器（使用自定义数据源）
    @Bean(name = MysqlTransactionManager)
    @Primary
    public DataSourceTransactionManager mysqlTransactionManager(
            @Qualifier(MysqlDataSource) DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    // 4.SqlSessionTemplate
    @Bean(name = MysqlSqlSessionTemplate)
    @Primary
    public SqlSessionTemplate mysqlSqlSessionTemplate(
            @Qualifier(MysqlSqlSessionFactory) SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}
